Technical Note TNxxxx
Scriptable Printing on Mac OS X

目次

Mac OS X の最初のバージョンにおけるプリントシステムでは、print アップルイベントを限定的にサポートしてましたが、プリントを行うアプリケーションに対してオプションや設定を指定する方法がありませんでした。Mac OS X 10.3(Panther)以降のプリントシステムでは、スクリプト作成者がプリント部数、丁合、ページ範囲などの設定を指定できる拡張された print アップルイベントをサポートしています。 この文書では、拡張された print イベントと、新しいスクリプタブル機能をサポートするためにアプリケーションに加える必要のある変更を説明します。プリンタモジュールと CUPS フィルタは変更の必要がありません。

[2003 年 12 月 9 日]






拡張された print アップルイベント

Mac OS X 10.3 以降では、print アップルイベントが拡張され、1 つまたは複数のプリントジョブの設定を指定する print settings という省略可能なパラメータと、アプリケーションがプリントダイアログを表示するかどうかを指定する print dialog という省略可能なパラメータが追加されました。デフォルトでは、呼び出し元が print dialog パラメータを指定しない限り、アプリケーションからプリントダイアログを表示しないようにします。

print: 指定された 1 つまたは複数のオブジェクトをプリントする

print reference -- プリントするオブジェクト。ファイルのリストまたはオブジェクト指定子を指定できます

[with properties print settings] -- プリント設定
[print dialog boolean] -- アプリケーションがプリントダイアログを表示するべきかどうか

スクリプト作成者は、print settings パラメータを使用して次の情報を指定できます。

Class print settings:

プロパティ:

copies integer [r/o] -- プリントする書類の部数
collating boolean [r/o] -- プリントの丁合をとるかどうか
starting page integer [r/o] -- 書類からプリントする最初のページ
ending page integer [r/o] -- 書類からプリントする最後のページ
pages across integer [r/o] -- 物理的なページ上に横方向に並べる論理ページの数
pages down integer [r/o] -- 物理的なページ上に縦方向に並べる論理ページの数
requested print time date [r/o] -- デスクトッププリンタが書類をプリントするべき時間
error handling standard/summarized/detailed [r/o] -- エラーの処理方法
fax number text [r/o] -- 書類の送信先ファックス番号
target printer text [r/o] -- 出力先のプリントキューの名前


たとえば、次のスクリプトはプリントダイアログを表示した後、“Prints Charming”というプリンタで書類の 2 ページ目を 3 部プリントします。



set theDoc to alias "Macintosh HD:ReadMe"
set printConfig to {copies:3, starting page:2, ending page:2,
    target printer:"Prints Charming"}
print theDoc with properties printConfig with print dialog


print イベントに対してこれらの省略可能なパラメータを指定することで、従来よりも詳細にプリントを制御できます。

先頭に戻る


アプリケーションに必要となる変更

アプリケーションは、print イベントの省略可能パラメータ print settings をサポートするために変更を加える必要があります。アプリケーションに加える必要のある変更を最小限にするためにあらゆる努力が払われましたが、実際に必要となる作業の量は、アプリケーションのプリント用コードの現在の状況によります。この節では、拡張された print イベントをサポートするために必要な変更を説明します。また、この文書に合わせて、アプリケーションにスクリプタブルプリントのサポート機能を追加する方法を示すサンプルコードも用意しています。

サンプルコードをダウンロード

アプリケーションを更新してスクリプタブルプリントと省略可能パラメータをサポートするには、4 つの手順が必要です。

  1. アプリケーションの 'aete' リソースを更新して、print の新しい省略可能パラメータと print settings クラスに対するサポートを示します。この文書のために用意したサンプルコードの「AESupport.r」に、'aete' の例が含まれています。
  2. アプリケーションの print イベントハンドラに変更を加えて、省略可能パラメータ print settings を処理できるようにします。print イベントに対する省略可能パラメータ print settings は、keyAEPropData というキーを使用します。アプリケーションの print ハンドラは、keyAEPropData パラメータを取得し、AEGetParamPtr を使用して 1 ステップでパラメータを PMPrintSettings オブジェクトにタイプ変換します。省略可能パラメータを PMPrintSettings オブジェクトに正しく変換できたら、それらのプリント設定を現在のプリントジョブに使用します。プリントする書類の PMPageFormat 情報は、書類と一緒に保存されているページ設定または新規のデフォルトのページ設定に基づきます。
  3. 省略可能パラメータ print settingstarget printer オブジェクトが含まれているかどうか調べるために、AEGetParamPtr にキーとして keyAEPropData、タイプとして kPMPrinterAEType を指定して呼び出します。その結果得られた PMPrinter が NULL でなければ、MPSessionSetCurrentPrinter を呼び出して、それをプリントセッションのターゲットプリンタとして使用します。
  4. 最後に、アプリケーションがユーザに対してプリントダイアログを表示するべきかどうかを指定する省略可能パラメータ print dialog の有無を調べます。このパラメータが省略されている場合、プリントダイアログを表示しないようにします。1 つの print イベントで複数の書類をプリントするときは、プリントダイアログは一度だけ表示し、そのときの設定をすべての書類で使用するようにします。

次のコードは、省略可能パラメータ print settings に含まれている PMPrinterSettings オブジェクトを取得、変換、および使用する方法を示します。



OSErr AEPrintDocument ( const AppleEvent *inputEvent,
                             AppleEvent *outputEvent,
                             SInt32 handlerRefCon )
{
#pragma unused (outputEvent,handlerRefCon)

    assert( inputEvent != NULL );

    OSStatus        status = noErr;
    PMPrintSettings printSettings = kPMNoPrintSettings;
    PMPrinter       printer = NULL;
    Boolean         showPrintDialog = false;
    PMPrintSession  session = NULL;
    PMPageFormat    pageFormat = kPMNoPageFormat;
    Boolean         printIt = true;

    #define kDontCare NULL
    
    //  次のセクションで、受け取ったアップルイベントからパラメータを取り出す。
    //  すべてが省略可能なので、ステータスは無視する。
    //  つまり、データがなければそのまま次の進む。

    //  プリント設定を取得する。
    //  プリント設定が指定されていない場合もある。
    //  その場合には、後でデフォルトのプリント設定を使用する。
    status = AEGetParamPtr( inputEvent,
                            keyAEPropData, kPMPrintSettingsAEType,
                            kDontCare, &printSettings,
                            sizeof( void* ), kDontCare );
    
    //  プリンタが指定されていれば、それを取得する。
    //  ターゲットプリンタが指定されていない場合もある。
    status = AEGetParamPtr( inputEvent,
                            keyAEPropData, kPMPrinterAEType,
                            kDontCare, &printer, sizeof( void* ),
                            kDontCare );

    //  プリントダイアログを表示するべきかどうかを調べる。デフォルトでは表示しない。
    status = AEGetParamPtr( inputEvent,
                            kPMShowPrintDialogAEType, typeBoolean,
                            kDontCare, &showPrintDialog,
                            sizeof( Boolean ), kDontCare );

    //  イベントから PMPrintSettings、PMPrinter、および showPrintDialog の
    //  各項目を取得したので、ファイルをプリントする。
    //  プリントを実行するためのセッションを作成する。
    status = PMCreateSession( &session );
    
    if ( status == noErr )
    {
        // ターゲットプリンタを出力先として設定する
        if ( printer != NULL )
        {
            status = PMSessionSetCurrentPMPrinter( session, printer);
        }
    
        //  スクリプト作成者が特定のプリント設定を要求していなければ、
        //  デフォルトの設定をロードする。
        if ( printSettings == kPMNoPrintSettings )
        {
            status = PMCreatePrintSettings( &printSettings );
            if ( status == noErr )
            {
               status = PMSessionDefaultPrintSettings(session,
                                                      printSettings);
            }
        }
    
        //  デフォルトの PMPageFormat を作成する。
        //  実際のアプリケーションでは、書類とともに格納されているページ設定を
        //  展開し、それを使用する。
        status = PMCreatePageFormat(&pageFormat);
        
        if ( (status == noErr) && (pageFormat != kPMNoPageFormat) )
        {
            PMSessionDefaultPageFormat(session, pageFormat);
        }
    
        //  プリントダイアログを表示するかどうかを調べる。
        //  プリントダイアログは、1 つの pdoc イベントに対して一度だけ表示する。
        //  その結果取得した設定をイベントのすべてのファイルに使用する。
        if ( showPrintDialog )
        {
            status = PMSessionPrintDialog( session, printSettings,
                                           pageFormat, &printIt );
        }

        if ( printIt )
        {
            AEDescList      docList;
            long            index, itemsInList;
            
            // ファイルのリストを取得する
            status = AEGetParamDesc( inputEvent, keyDirectObject,
                                     typeAEList, &docList );
    
            if ( status == noErr )
            {
                //  プリントするファイルの数を取得する
                status = AECountItems( &docList, &itemsInList );
    
                //  ファイルのリストを反復処理する
                for ( index = 1; index <= itemsInList; index++ )
                {
                    AEKeyword       keywd;
                    DescType        returnedType;
                    Size            actualSize;
                    HFSUniStr255    fileName;
                    CFStringRef     fileNameRef=NULL;
                    WindowRef       windowRef = NULL;
                    char            buffer[ kFileBufferSize ];
                    long            count = sizeof( buffer );
                    FSRef fileRef;
    
                    // ファイル参照を取得する
                    status = AEGetNthPtr( &docList, index, typeFSRef,
                                          &keywd, &returnedType,
                                          (Ptr)(&fileRef), 
                                          sizeof( fileRef ), 
                                          &actualSize );
    
                    // ウィンドウのタイトルに使用するファイル名を取得する
                    if ( status == noErr )
                    {
                        status = FSGetCatalogInfo( &fileRef, 0, NULL,
                                                   &fileName,
                                                   NULL, NULL );
                    }
                    
                    if ( status == noErr )
                    {
                        fileNameRef = CFStringCreateWithCharacters(
                                        kCFAllocatorDefault,
                                        &fileName.unicode[0], 
                                        fileName.length );
                    }
    
                    // ファイルを読み取りのために開く
                    if ( status == noErr )
                    {
                        status = ReadFileData( fileRef, &count,
                                               &buffer[0] );
                        if ( status == noErr )
                        {
                            //  書類ウィンドウのサンプルを表示する
                            windowRef = ShowDocumentWindow(
                                          fileNameRef,buffer,count);
    
                            status = PrintDocument( session,
                                       printSettings, pageFormat,
                                       fileNameRef, buffer );
    
                            //  ファイル名文字列は用済み
                            CFRelease( fileNameRef );
    
                            //  ウィンドウは用済み
                            DisposeWindow( windowRef );
                        }
                    }
                }
            }
        }
        
        // 後始末
        PMRelease( pageFormat );
        PMRelease( session );
    }

    //  完了したのですべて解放する
    PMRelease( printSettings );
    PMRelease( printer );

    return status;
}   //  AEPrintDocument


先頭に戻る


要約

プリント処理を従来よりも詳細に制御するスクリプトの作成を可能にする Mac OS X 10.3 の拡張された print アップルイベントを紹介しました。アプリケーションがこのスクリプト機能をサポートするには、プリントループに変更を加えて、省略可能パラメータを処理する必要があります。これらの変更により、より柔軟性の高いプリントが可能となるため、AppleScript のユーザにとっては大きなメリットとなります。

先頭に戻る


参考文献

Mac OS X プリンティングのデベロッパ向けのページ

Mac OS X プリンティング技術文書

Mac OS X プリンティングの Q&A

Mac OS X プリンティング Technotes

AppleScript デベロッパ向けのページ

Mac OS X 上の AppleScript

AppleScript に関する文書

先頭に戻る


ダウンロード

Binhexed

サンプルコード

ダウンロード


先頭に戻る